﻿namespace DataMorph.Web.Services
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using System.Threading;

    using DataMorph.Common;
    using DataMorph.Processing;

    public class ProgressReader : IProgressReader
    {
        private readonly GenerationParameters generationParameters;

        private readonly IProgressQueue progressQueue;

        private int filesProcessed;

        private bool running;

        public ProgressReader(IProgressQueue progressQueue, GenerationParameters generationParameters)
        {
            this.generationParameters = generationParameters;
            this.progressQueue = progressQueue;
        }

        public event EventHandler<ProgressChangedEventArgs> ProgressChanged;

        public void Start()
        {
            this.running = true;
            
            while (this.running)
            {
                var messages = this.ReadProgressReports().ToList();
                if (messages.Any())
                {
                    this.filesProcessed += messages.Where(x => x.StorageAccount.Equals(this.generationParameters.StorageAccountName)).Count(x => x.DataSetName.Equals(this.generationParameters.Name));

                    this.RaiseProgressChangedEvent(Convert.ToInt32(((double)this.filesProcessed / this.generationParameters.NumberOfFiles) * 100), this.filesProcessed);

                    foreach (var message in messages)
                    {
                        this.progressQueue.DeleteProgressReport(message);
                    }

                    if (this.filesProcessed == this.generationParameters.NumberOfFiles)
                    {
                        this.Stop();
                        break;
                    }
                }
                else
                {
                    Thread.Sleep(TimeSpan.FromSeconds(10));
                }
            }
        }

        public void Stop()
        {
            this.running = false;
        }

        private IEnumerable<FileProcessedMessage> ReadProgressReports()
        {
            return this.progressQueue.GetProgressReports();
        }

        private void RaiseProgressChangedEvent(int progress, int filesProcessed)
        {
            if (this.ProgressChanged != null)
            {
                this.ProgressChanged(this, new ProgressChangedEventArgs(progress, filesProcessed));
            }
        }
    }
}